#!/usr/bin/env python

# Demonstration client script for Freebase's OAuth implementation
#  
# Author:  Kurt Bollacker, May 2010 (with cribbing from Alec Flett)
# Copyright: Public Domain
#
# 

import oauth,urlparse,urllib,urllib2,json


# Put your consumer key and secret here!
CONSUMER_KEY = 'YOUR APPPLICATION CONSUMER KEY (A FREEBASE GUID)'
CONSUMER_SECRET = 'YOUR APPLICATION CONSUMER SECRET'

# Define default callback and ondecline 
CALLBACK_URL = 'http://MYSERVER:7777/getaccesstoken'
DECLINE_URL = 'http://MYSERVER:7777/failed'

# These URLs should work for production
#REQUEST_TOKEN_URL = 'https://api.freebase.com/api/oauth/request_token'
#ACCESS_TOKEN_URL = 'https://api.freebase.com/api/oauth/access_token'
#AUTHORIZATION_URL = 'https://www.freebase.com/signin/authorize_token'
#USER_INFO_URL='http://freebase.com/api/service/user_info'
#MQL_WRITE_URL='http://api.freebase.com/api/service/mqlwrite'

# These URLs should work for sandbox
REQUEST_TOKEN_URL = 'https://api.sandbox-freebase.com/api/oauth/request_token'
ACCESS_TOKEN_URL = 'https://api.sandbox-freebase.com/api/oauth/access_token'
AUTHORIZATION_URL = 'https://sandbox-freebase.com/signin/authorize_token'
USER_INFO_URL='http://api.sandbox-freebase.com/api/service/user_info'
MQL_WRITE_URL='http://api.sandbox-freebase.com/api/service/mqlwrite'


def fetch_url(url, http_method='GET',headers={},body=None):
    ''' Fetch the given URL, cleaning up headers if needed'''

    headers.update({'X-Requested-With':'MyTestScript',
                    'X-Metaweb-Request':'True',
                    'Content-Type': 'application/x-www-form-urlencoded'})
   
    if http_method=='POST' and body==None:
        body=''
    if body!=None:
        headers['Content-Length']=str(len(body))

    print "HTTP METHOD = %s\n " % http_method
    print "HEADERS = %s\n " % json.dumps(headers)
    print "URL = %s\n" % url
    print "BODY = %s\n" % body

    req=urllib2.Request(url,body,headers)
    try:
        response=urllib2.urlopen(req)
    except urllib2.HTTPError,e:
        print e
        return None
    print response.getcode()
    if response.getcode() != 200:
        print "GETCODE "+str(response.getcode())+" MSG "+response.msg+" INFO "+response.info+" READ "+response.read()

    return response.read()



def get_request_token():
    consumer=oauth.OAuthConsumer(CONSUMER_KEY,CONSUMER_SECRET)
    request=oauth.OAuthRequest.from_consumer_and_token(consumer,
                                                       http_method='GET',
                                                       http_url=REQUEST_TOKEN_URL)
    request.sign_request(oauth.OAuthSignatureMethod_HMAC_SHA1(),consumer,None)
    
    r=fetch_url(REQUEST_TOKEN_URL,
                http_method='GET',
                headers=request.to_header())
    
    result=dict([p.split('=') for p in r.split('&')])
    return  result

def authorize_token_url(request_token_key,callback=CALLBACK_URL,decline=DECLINE_URL):
    return AUTHORIZATION_URL+'?oauth_token='+request_token_key+'&oauth_callback='+callback+'&ondecline='+decline
    
def get_access_token(key,secret):
    requestToken=oauth.OAuthToken(key,secret)
    consumer=oauth.OAuthConsumer(CONSUMER_KEY,CONSUMER_SECRET)
    request=oauth.OAuthRequest.from_consumer_and_token(consumer,
                                                       http_method='GET',
                                                       token=requestToken,
                                                       http_url=ACCESS_TOKEN_URL)
    request.sign_request(oauth.OAuthSignatureMethod_HMAC_SHA1(),consumer,requestToken)
    
    r=fetch_url(ACCESS_TOKEN_URL,
                http_method='GET',
                headers=request.to_header())
    result=dict([p.split('=') for p in r.split('&')])
    return result
                
    
def freebase_user_info(key,secret):
    ''' Do a test of the Freebase user_info service '''

    token=oauth.OAuthToken(key,secret)
    consumer=oauth.OAuthConsumer(CONSUMER_KEY,CONSUMER_SECRET)
    request=oauth.OAuthRequest.from_consumer_and_token(consumer,
                                                       http_url=USER_INFO_URL,
                                                       http_method='POST',
                                                       token=token)

    request.sign_request(oauth.OAuthSignatureMethod_HMAC_SHA1(),consumer,token)

    headers=request.to_header()

    r=fetch_url(USER_INFO_URL,
                http_method='POST',
                headers=headers)
    
    return r

def freebase_mqlwrite(key,secret):
    ''' Do a test of the Freebase MQL write service '''

    token=oauth.OAuthToken(key,secret)
    consumer=oauth.OAuthConsumer(CONSUMER_KEY,CONSUMER_SECRET)

    queryenvelope = {"q":{"query": {"id":None,
                                    "create":"unconditional"}}}
    querybody={'queries':json.dumps(queryenvelope)}

    request=oauth.OAuthRequest.from_consumer_and_token(consumer,
                                                       http_url=MQL_WRITE_URL,
                                                       http_method='POST',
                                                       token=token,
                                                       parameters=querybody)

    request.sign_request(oauth.OAuthSignatureMethod_HMAC_SHA1(),consumer,token)

    headers=request.to_header()

    r=fetch_url(MQL_WRITE_URL,
                http_method='POST',
                body=urllib.urlencode(querybody),
                headers=headers)
    
    return r

if __name__=='__main__':

    # Make sure to define consumer key/secret and callback url in defaults at the top of this script.

    # Get request token
    print "Getting Request Token\n"
    reqtok=get_request_token()
    
    print "Our request token is = ",reqtok
        
    # Assemble an authorization URL
    print "Authorizing Request Token\n"
    authorizeurl=authorize_token_url(reqtok['oauth_token'])
        
    # Wait for the user to authorize
    raw_input("Visit the URL= "+authorizeurl+" and then press return.")
        
    # Get our access token
    print "Getting Access Token\n"
    acctok=get_access_token(reqtok['oauth_token'],reqtok['oauth_token_secret'])
    
    print "Our access token is = ",acctok

    # As a test, call Freebase's API for user information and MQL write

    print "Getting Freebase User Info\n"
    print freebase_user_info(acctok['oauth_token'],acctok['oauth_token_secret'])

    print "Performing a Freebase Test Write\n"
    print freebase_mqlwrite(acctok['oauth_token'],acctok['oauth_token_secret'])
